package pikes.peak;

import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.Map;

import org.springframework.web.servlet.support.RequestContext;

import pikes.html.xhtml.Block;
import pikes.html.xhtml.table.TBody;
import pikes.html.xhtml.table.THead;
import pikes.html.xhtml.table.TR;
import pikes.html.xhtml.table.Table;
import pikes.html.xhtml.text.NonBreakingSpace;

public class Grid implements BlockComponent {

	public static final RequestProperty<TR> DEFAULT_ROW = new RequestIndependentProperty<TR>(new TR(
			new NonBreakingSpace()));

	public static final RequestProperty<Collection<RequestProperty<TR>>> DEFAULT_ROWS_PROVIDER = new RequestIndependentProperty<Collection<RequestProperty<TR>>>(
			Collections.singletonList(DEFAULT_ROW));

	private GridDecorator gridDecorator = GridDecorator.NULL_DECORATOR;

	private RequestProperty<Collection<RequestProperty<TR>>> headerRowsProvider = RequestProperty.EMPTY_COLLECTION;

	private RequestProperty<Collection<RequestProperty<TR>>> rowsProvider = DEFAULT_ROWS_PROVIDER;

	public Grid() {
		this(GridDecorator.NULL_DECORATOR);
	}

	public Grid(final GridDecorator gridDecorator) {
		this.gridDecorator = gridDecorator;
	}

	public final Block createHtml(Map model, RequestContext requestContext) throws Exception {
		Table table = null;

		Collection<RequestProperty<TR>> rows = rowsProvider.getValue(model, requestContext);
		if (!rows.isEmpty()) {
			Iterator<RequestProperty<TR>> iRows = rows.iterator();

			RequestProperty<TR> firstRow = iRows.next();

			TBody tbody = new TBody(firstRow.getValue(model, requestContext));

			while (iRows.hasNext()) {
				tbody.add(iRows.next().getValue(model, requestContext));
			}

			table = new Table(tbody);
		}

		Collection<RequestProperty<TR>> headerRows = headerRowsProvider.getValue(model, requestContext);
		if (!headerRows.isEmpty()) {
			Iterator<RequestProperty<TR>> iHeaderRows = headerRows.iterator();

			RequestProperty<TR> firstHeaderRow = iHeaderRows.next();

			THead thead = new THead(firstHeaderRow.getValue(model, requestContext));

			while (iHeaderRows.hasNext()) {
				thead.add(iHeaderRows.next().getValue(model, requestContext));
			}

			table.setHeader(thead);
		}

		gridDecorator.decorateTable(table, model, requestContext);

		return table;
	}

	public final void setHeaderRows(Collection<RequestProperty<TR>> headerRows) {
		setHeaderRows(new RequestIndependentProperty<Collection<RequestProperty<TR>>>(headerRows));

	}

	public final void setHeaderRows(RequestProperty<Collection<RequestProperty<TR>>> headerRows) {
		if (headerRows == null) {
			this.headerRowsProvider = RequestProperty.EMPTY_COLLECTION;
		}
		else {
			this.headerRowsProvider = headerRows;
		}

	}

	public final RequestProperty<Collection<RequestProperty<TR>>> getHeaderRows() {
		return headerRowsProvider;
	}

	public final void setRow(RequestProperty<TR> row) {
		setRows(Collections.singletonList(row));
	}

	public final void setRows(Collection<RequestProperty<TR>> rows) {
		setRows(new RequestIndependentProperty<Collection<RequestProperty<TR>>>(rows));

	}

	public final void setRows(RequestProperty<Collection<RequestProperty<TR>>> rows) {
		if (rows == null) {
			this.rowsProvider = Grid.DEFAULT_ROWS_PROVIDER;
		}
		else {
			this.rowsProvider = rows;
		}

	}

	public final RequestProperty<Collection<RequestProperty<TR>>> getRows() {
		return rowsProvider;
	}
}
